/*
MoniBabyTor - a webcam based monitoring app for babies
    Copyright (C) 2013 Assaf Paz

    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU General Public License for more details.

    You should have received a copy of the GNU General Public License
    along with this program.  If not, see <http://www.gnu.org/licenses/>.
*/
#include "mainwindow.h"
#include "ui_mainwindow.h"
#include <QVideoSurfaceFormat>
#include <QInputDialog>

MainWindow::MainWindow(SettingsDataModel &dataModel, MJpegFile &mjpegFile, QWidget *parent) :
    QMainWindow(parent),
    ui(new Ui::MainWindow),
    _dataModel(dataModel),
    _mjpegFile(mjpegFile),
    _videoFormatInitialized(false),
    _isStarted(false)
{
    _videoWidget = new VideoWidget(this);
    ui->setupUi(this);

    ui->videoPlaceholder->addWidget(_videoWidget, 0, 0);

    ui->tabWidget->setCurrentIndex(0);

    ui->presets->addItems(_dataModel.presets());

    int presetIndex = ui->presets->findText(_dataModel.preset());
    ui->presets->setCurrentIndex((presetIndex == -1)? 0 : presetIndex);
    loadSettings();

    QString videoTimeout = QString().sprintf("%d",_dataModel.videoTimeout());
    ui->videoTimeout->setCurrentIndex(ui->videoTimeout->findText(videoTimeout));

    connect(&_mjpegFile, SIGNAL(imageReceived(QImage*)), this, SLOT(addImage(QImage*)));

    connect(&_dataModel, SIGNAL(error(QString)), ui->error, SLOT(setText(QString)));
    connect(&_dataModel, SIGNAL(rmsLevelChanged(int)), ui->rmsLevel, SLOT(setValue(int)));
    connect(this, SIGNAL(startRequested()), &_dataModel, SIGNAL(startRequested()));
    connect(this, SIGNAL(stopRequested()), &_dataModel, SIGNAL(stopRequested()));
    connect(&_dataModel, SIGNAL(videoTimeoutRequested()), this, SLOT(onVideoTimeout()));
    connect(&_dataModel, SIGNAL(showSettingsRequested()), this, SLOT(showSettings()));
    connect(ui->quickViewButton, SIGNAL(clicked()), &_dataModel, SIGNAL(quickViewRequested()));

    connect(ui->addPresetButton, SIGNAL(clicked()), this, SLOT(addPresetButtonClicked()));
    connect(ui->removePresetButton, SIGNAL(clicked()), this, SLOT(removePresetButtonClicked()));
    connect(ui->loadPresetButton, SIGNAL(clicked()), this, SLOT(loadPresetButtonClicked()));
    connect(ui->videoURL, SIGNAL(textChanged(QString)), &_dataModel, SLOT(setVideoUrl(QString)));
    connect(ui->audioURL, SIGNAL(textChanged(QString)), &_dataModel, SLOT(setAudioUrl(QString)));
    connect(ui->userName, SIGNAL(textChanged(QString)), &_dataModel, SLOT(setUsername(QString)));
    connect(ui->password, SIGNAL(textChanged(QString)), &_dataModel, SLOT(setPassword(QString)));
    connect(ui->audioSensitivity, SIGNAL(valueChanged(int)), &_dataModel, SLOT(setSensitivity(int)));
    connect(ui->audioSensitivity, SIGNAL(valueChanged(int)), ui->rmsLevel, SLOT(setThershold(int)));
    connect(ui->videoTimeout, SIGNAL(currentIndexChanged(QString)), &_dataModel, SLOT(setVideoTimeout(QString)));
    connect(ui->outputVolume, SIGNAL(valueChanged(int)), &_dataModel, SLOT(setOutputVolume(int)));

    connect(&_dataModel, SIGNAL(refreshSettingsRequested()), this, SLOT(loadSettings()));
}

MainWindow::~MainWindow()
{
    delete _videoWidget;
    delete ui;
}

void MainWindow::addImage(QImage *image)
{
    QVideoFrame frame(*image);
    if (_videoFormatInitialized == false)
    {
        _videoFormatInitialized = true;
        QVideoSurfaceFormat format = QVideoSurfaceFormat(image->size(), frame.pixelFormat());
        _videoWidget->videoSurface()->start(format);
    }
    _videoWidget->videoSurface()->present(frame);
    delete image;
}

void MainWindow::onVideoTimeout()
{
    _videoWidget->videoSurface()->stop();
    _videoFormatInitialized = false;
}

void MainWindow::on_actionButton_clicked()
{
    ui->presets->setEnabled(_isStarted);
    ui->addPresetButton->setEnabled(_isStarted);
    ui->loadPresetButton->setEnabled(_isStarted);
    ui->removePresetButton->setEnabled(_isStarted);
    ui->videoURL->setEnabled(_isStarted);
    ui->audioURL->setEnabled(_isStarted);
    ui->userName->setEnabled(_isStarted);
    ui->password->setEnabled(_isStarted);

    if (_isStarted)
    {
        _isStarted = false;
        ui->actionButton->setText("Start");
        emit stopRequested();
    }
    else
    {
        _isStarted = true;
        ui->actionButton->setText("Stop");
        ui->tabWidget->setCurrentIndex(1);
        emit startRequested();
    }
}

void MainWindow::showSettings()
{
    ui->tabWidget->setCurrentIndex(0);
}

void MainWindow::addPresetButtonClicked()
{
    bool ok;
    QString text = QInputDialog::getText(this, tr("Save Preset"),
                                         tr("Preset name:"), QLineEdit::Normal,
                                         _dataModel.preset(), &ok);
    if (ok && !text.isEmpty())
    {
        if (text != _dataModel.preset())
        {
            ui->presets->addItem(text);
            int presetIndex = ui->presets->findText(text);
            ui->presets->setCurrentIndex((presetIndex == -1)? 0 : presetIndex);
        }

        _dataModel.savePreset(text);
        refreshOnPresetChanged();
    }
}

void MainWindow::removePresetButtonClicked()
{
    QString currentPreset = ui->presets->currentText();
    _dataModel.removePreset(currentPreset);

    int presetIndex = ui->presets->findText(currentPreset);
    ui->presets->removeItem(presetIndex);

    if (presetIndex >= ui->presets->count())
    {
        presetIndex--;
    }

    ui->presets->setCurrentIndex(presetIndex);

    QString followingPreset = ui->presets->model()->index(presetIndex, 0).data().toString();

    _dataModel.setPreset(followingPreset);
    _dataModel.loadPreset(followingPreset);
}

void MainWindow::loadPresetButtonClicked()
{
    _dataModel.setPreset(ui->presets->currentText());
    _dataModel.loadPreset(ui->presets->currentText());
}

void MainWindow::loadSettings()
{
    ui->videoURL->setText(_dataModel.videoUrl());
    ui->audioURL->setText(_dataModel.audioUrl());
    ui->userName->setText(_dataModel.username());
    ui->password->setText(_dataModel.password());
    ui->audioSensitivity->setValue(_dataModel.sensitivity());
    ui->rmsLevel->setThershold(_dataModel.sensitivity());
    ui->outputVolume->setValue(_dataModel.outputVolume());

    refreshOnPresetChanged();
}

void MainWindow::refreshOnPresetChanged()
{
    bool isSystemPreset = _dataModel.isSystemPreset();
    ui->videoURL->setEnabled(!isSystemPreset);
    ui->audioURL->setEnabled(!isSystemPreset);
    ui->userName->setEnabled(!isSystemPreset);
    ui->password->setEnabled(!isSystemPreset);
    ui->audioSensitivity->setEnabled(!isSystemPreset);
    ui->rmsLevel->setEnabled(!isSystemPreset);
    ui->outputVolume->setEnabled(!isSystemPreset);
    ui->videoTimeout->setEnabled(!isSystemPreset);
}
